/*
 * @Descripttion:
 * @version:
 * @Author: sueRimn
 * @Date: 2025-05-22 21:43:33
 * @LastEditors: sueRimn
 * @LastEditTime: 2025-08-26 19:53:26
 */
#include "public.h"

#include "power.h"

#include "iic.h"

#include "stdio.h"

#include "task.h"

int8_t power_init(void)
{
    POUT_24V_CT1_ON;
    POUT_24V_CT2_ON;

    POUT_12V_CT1_ON;
    POUT_12V_CT2_ON;

    POUT_5V_CT_ON;

    PDEV_5V_ON;

    PCHARG_ON;

    INA_init();

    return 0;
}

int8_t INA_init(void)
{
    uint8_t read_data[2];
    uint8_t write_data[2];
    INA_IIC_Read_Regs(INA_ADDR_0, ID_Reg, read_data, 2);
    printf("INA0_ID = %x%x\r\n", read_data[0], read_data[1]);

    INA_IIC_Read_Regs(INA_ADDR_0, Man_ID_Reg, read_data, 2);
    printf("IN0A_MAN_ID = %x%x\r\n", read_data[0], read_data[1]);

    INA_IIC_Read_Regs(INA_ADDR_3, ID_Reg, read_data, 2);
    printf("INA3_ID = %x%x\r\n", read_data[0], read_data[1]);

    INA_IIC_Read_Regs(INA_ADDR_3, Man_ID_Reg, read_data, 2);
    printf("INA3_MAN_ID = %x%x\r\n", read_data[0], read_data[1]);

    write_data[0] = 0x45;
    write_data[1] = 0x27;
    INA_IIC_Write_Regs(INA_ADDR_0, Config_Reg, write_data, 2);	//0100_010_100_100_111 //16次平均,1.1ms,1.1ms,连续测量分流电压和总线电压
    INA_IIC_Write_Regs(INA_ADDR_3, Config_Reg, write_data, 2);	//0100_010_100_100_111 //16次平均,1.1ms,1.1ms,连续测量分流电压和总线电压

    write_data[0] = 0x0a;
    write_data[1] = 0x00;
    INA_IIC_Write_Regs(INA_ADDR_0, Calib_Reg, write_data, 2);	// 分辨率0.2mA 采样电阻0.01 CAL = 0.00512/(0.2*0.01)*1000 = 2560= 0xa00
    INA_IIC_Write_Regs(INA_ADDR_3, Calib_Reg, write_data, 2);

    return 0;
}

const int32_t aiElePointsMv[] = {
    25200,  // 25.20V ×1000 → 100%
    24360,  // 24.36V ×1000 → 90%
    23880,  // 23.88V ×1000 → 80%
    23520,  // 23.52V ×1000 → 70%
    22920,  // 22.92V ×1000 → 50%
    22440,  // 22.44V ×1000 → 30%
    22080,  // 22.08V ×1000 → 10%
    18000   // 18.00V ×1000 → 0%
};

const int32_t aiPointsPercent[] = { 100, 90, 80, 70, 50, 30, 10, 0 }; // 电量百分比

/*
 * @brief 通过放大1000倍的电压值计算电量百分比
 * @param voltage_x1000 电压值×1000（int16_t类型，范围 -32768~32767）
 * @return 电量百分比（0~100整数）
 */
int16_t calculateEle()
{

    if (pstDev->stDevBat.sVolVal >= aiElePointsMv[0]) return 100;
    if (pstDev->stDevBat.sVolVal <= aiElePointsMv[7]) return 0;

    for (int i = 0; i < 7; i++)
    {
        if (pstDev->stDevBat.sVolVal > aiElePointsMv[i + 1] && pstDev->stDevBat.sVolVal <= aiElePointsMv[i])
        {
            int32_t voltage_range = aiElePointsMv[i] - aiElePointsMv[i + 1];
            int32_t soc_range = aiPointsPercent[i] - aiPointsPercent[i + 1];

            int32_t position = aiElePointsMv[i] - pstDev->stDevBat.sVolVal; // 当前电压与上限的差值
            int32_t soc = aiPointsPercent[i] - (position * soc_range) / voltage_range;

            return (int16_t)soc;
        }
    }
    return 0; // 默认返回0%
}

void chargCheck(void)
{

    // if(calculateEle() < 99)  //充到电池百分之99则判断为充满
    if(pstDev->stDevBat.sVolVal < 25180) //电池电压大于 25.18v判断为充满 有0.005v压降 所以大概为 25.185v为充满
    {
        if(pstDev->stDevCharg.sEleVal > 10) //充电电流>10ma判断为充电
        {
            setLedStat( LED_NULL, LED_NULL, LED_BREA);
            return ;
        }
    }
    setLedStat( LED_NULL, LED_NULL, LED_ON);
}

static void INA_Read(uint8_t ucInaChoose)// 1电池 0充电
{
    uint8_t v_data[2];
    uint8_t a_data[2];
    // uint8_t w_data[2];

    // float v_value;
    // float a_value;
    // float w_value;

    if (ucInaChoose == 1)
    {
        INA_IIC_Read_Regs(INA_ADDR_3, Bus_V_Reg, v_data, 2);
        INA_IIC_Read_Regs(INA_ADDR_3, Current_Reg, a_data, 2);

        // INA_IIC_Read_Regs(INA_ADDR_3, Power_Reg, w_data, 2);
        if ((v_data[0] & v_data[1] & a_data[0] & a_data[1]) == 0xff)
        {
            pstDev->stDevBat.eDevStat = SEN_ERR;
            pstDev->stDevBat.sVolVal = 0;
            pstDev->stDevBat.sEleVal = 0;
            // v_value = 0;
            // a_value = 0;
        }
        else
        {
            pstDev->stDevBat.eDevStat = SEN_NOR;
            pstDev->stDevBat.sVolVal = (int16_t)((float)((int16_t)(uint16_t)v_data[0] << 8 | v_data[1]) * 1.25f);
            pstDev->stDevBat.sEleVal = (int16_t)((float)((int16_t)(uint16_t)a_data[0] << 8 | a_data[1]) * 0.2f);
            // v_value = ((uint16_t)v_data[0] << 8 | v_data[1]) * 1250;
            // a_value = ((uint16_t)a_data[0] << 8 | a_data[1]) * 200;
            // w_value = ((uint16_t)w_data[0] << 8 | w_data[1]) * 0.02f * 25;
        }
    }
    else
    {
        INA_IIC_Read_Regs(INA_ADDR_0, Bus_V_Reg, v_data, 2);
        INA_IIC_Read_Regs(INA_ADDR_0, Current_Reg, a_data, 2);
        // INA_IIC_Read_Regs(INA_ADDR_0, Power_Reg, w_data, 2);
        if ((v_data[0] & v_data[1] & a_data[0] & a_data[1]) == 0xff)
        {
            pstDev->stDevCharg.eDevStat = SEN_ERR;
            pstDev->stDevCharg.sVolVal = 0;
            pstDev->stDevCharg.sEleVal = 0;
            // v_value = 0;
            // a_value = 0;
        }
        else
        {
            pstDev->stDevCharg.eDevStat = SEN_NOR;
            pstDev->stDevCharg.sVolVal = (int16_t)((float)((int16_t)((uint16_t)v_data[0] << 8 | v_data[1])) * 1.25f);
            pstDev->stDevCharg.sEleVal = (int16_t)((float)((int16_t)((uint16_t)a_data[0] << 8 | a_data[1])) * 0.2f);

            // v_value = ((uint16_t)v_data[0] << 8 | v_data[1]) * 1250;
            // a_value = ((uint16_t)a_data[0] << 8 | a_data[1]) * 200;
            // w_value = ((uint16_t)w_data[0] << 8 | w_data[1]) * 0.02f * 25;
        }
    }


    // w_value = ((uint16_t)w_data[0] << 8 | w_data[0]) * 0.02f * 25;

    // printf("v_value = %.2f\t a_value = %.2f\r\n", v_value, a_value);
    // printf("v_data = %x%x a_data = %x%x w_data = %x%x\r\n",v_data[0],v_data[1]
    // ,a_data[0],a_data[1],w_data[0],w_data[1]);
}



task_delay_t pstDelayPowerOnHandle;
task_delay_t pstDelayPowerOffHandle;

void powerOnDelayTask(void *param)//延时上电任务
{
    if (!pstDev->bIsOutPowerCtrlPerm)
    {
        //电源控制权限依旧在MCU
        POUT_24V_CT2_ON;

        POUT_12V_CT1_ON;
        POUT_12V_CT2_ON;

        POUT_5V_CT_ON;
        PDEV_5V_ON;

        printf("delay poweron\r\n");

    }

    setLedStat( LED_OFF, LED_OFF, LED_NULL);
}

void powerOffDelayTask(void *param)//延时下电任务
{
    if (!pstDev->bIsOutPowerCtrlPerm)
    {
        //电源控制权限依旧在MCU
        POUT_24V_CT1_OFF;       //这个时候是强制整机下电
        POUT_24V_CT2_OFF;

        POUT_12V_CT1_OFF;
        POUT_12V_CT2_OFF;

        POUT_5V_CT_OFF;
        PDEV_5V_OFF;

        printf("delay poweroff\r\n");


    }

    setLedStat(LED_OFF, LED_ON, LED_NULL);
}

void powerOn(void)
{
    POUT_24V_CT1_ON;//高通上电

    if (pstDelayPowerOnHandle == NULL)
    {
        pstDelayPowerOnHandle = delay_task_regist(10000, powerOnDelayTask, NULL);
    }

    delay_task_add_run_list(pstDelayPowerOnHandle);

    setLedStat(LED_BREA, LED_OFF, LED_NULL);

    pstDev->ucPowerStat = 1;

    pstDev->bIsOutPowerCtrlPerm = false;
}

void powerOff(void)
{
    if (pstDelayPowerOffHandle == NULL)
    {
        pstDelayPowerOffHandle = delay_task_regist(10000, powerOffDelayTask, NULL);
    }
    canReportSwitch(2, 0, 0);
    delay_task_add_run_list(pstDelayPowerOffHandle);

    setLedStat(LED_OFF, LED_BREA, LED_NULL);

    pstDev->ucPowerStat = 0;

    pstDev->bIsOutPowerCtrlPerm = false;
}

void powerRunTask()
{
    static uint8_t ucTimeCout = 0;

    INA_Read(0);
    INA_Read(1);

    chargCheck();
}

void powerCtrl(uint8_t *pucPowerCtrl)
{
    bool *pbPowerPort = &pstDev->stDevPowerSupply.bPower24VPort1;


    for (uint8_t i = 0; i < sizeof(power_supply_t) / sizeof(bool); i++)
    {
        *(pbPowerPort + i) = (bool)pucPowerCtrl[i];
    }

    if (pstDev->stDevPowerSupply.bPower24VPort1)
    {
        POUT_24V_CT1_ON;
    }

    else
    {
        POUT_24V_CT1_OFF;
    }

    if (pstDev->stDevPowerSupply.bPower24VPort2)
    {
        POUT_24V_CT2_ON;
    }
    else
    {
        POUT_24V_CT2_OFF;
    }

    if (pstDev->stDevPowerSupply.bPower12VPort1)
    {
        POUT_12V_CT1_ON;
    }
    else
    {
        POUT_12V_CT1_OFF;
    }

    if (pstDev->stDevPowerSupply.bPower12VPort2)
    {
        POUT_12V_CT2_ON;
    }
    else
    {
        POUT_12V_CT2_OFF;
    }

    if (pstDev->stDevPowerSupply.bPower5VPort)
    {
        POUT_5V_CT_ON;
    }
    else
    {
        POUT_5V_CT_OFF;
    }

    if (pstDev->stDevPowerSupply.bPowerDev5VPort)
    {
        PDEV_5V_ON;
    }
    else
    {
        PDEV_5V_OFF;
    }

    pstDev->bIsOutPowerCtrlPerm = true; //移交电源控制权给高通

    // pstDev->bIsSwitchPowerIng = false; //移交电源控制权给高通


    // printf("24v1 = %d  24v2 = %d 12v1 = %d 12v2 = %d 5v = %d\r\n",
    //     pstDev->stDevPowerSupply.bPower24VPort1,
    //     pstDev->stDevPowerSupply.bPower24VPort2,
    //     pstDev->stDevPowerSupply.bPower12VPort1,
    //     pstDev->stDevPowerSupply.bPower12VPort2,
    //     pstDev->stDevPowerSupply.bPower5VPort
    // );

}